<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>类继承</title>
    <script src="js/traceur.js"></script>
    <script src="js/bootstrap.js"></script>
    <script type="module">
        //继承
        function A(a) {
            this.a = a;
        }
        A.prototype.printA = function () {
            console.log(this.a);
        }
        class B extends A {
            constructor(a, b) {
                super(a);
                this.b = b;
            }

            static sayHello() {
                console.log("Hello");
            }

            printB() {
                console.log(this.b);
            }
        }
        class C extends B {
            constructor(a, b, c) {
                super(a, b);
                this.c = c;
            }

            printC() {
                console.log(this.c);
            }

            printAll() {
                this.printC();
                super.printB();
                super.printA();
                //super.sayHello(); //无法访问到
            }
        }
        var obj = new C(1, 2, 3);
        obj.printAll();
        C.sayHello();


        //使用计算机方法来命令类行为
        class myClass {
            static ["my" + "Method"]() {
                console.log("Hello");
            }
        }
        myClass["my" + "Method"](); // "Hello"

        //使用符号来作为方法的行为名称
        var s = Symbol("Sample");
        class myClass1 {
            static [s]() {
                console.log("Hello");
            }
        }
        myClass1[s](); // "Hello"

        class myClass2 {
            constructor() {
                return Object.create(null);
            }
        } //并没有返回新的实例
        console.log(new myClass2() instanceof myClass2); //"false"

        //@@ species static accessor属性可选地添加到子构造函数中，以便发出父构造函数的方法
        class myCustomArray1 extends Array {
            static get [Symbol.species]() {
                return Array;
            }
        }
        class myCustomArray2 extends Array {
        }
        var arr1 = new myCustomArray1(0, 1, 2, 3, 4);
        var arr2 = new myCustomArray2(0, 1, 2, 3, 4);
        console.log(arr1 instanceof myCustomArray1); // true
        console.log(arr2 instanceof myCustomArray2); // ture
        arr1 = arr1.map(function (value) {
            return value + 1;
        })
        arr2 = arr2.map(function (value) {
            return value + 1;
        })
        //@@ species的使用 - 数组对象的map（）方法返回一个新的Array实例。
        console.log(arr1 instanceof myCustomArray1); // false
        console.log(arr2 instanceof myCustomArray2); // true
        console.log(arr1 instanceof Array); //true
        console.log(arr2 instanceof Array); //false

        //库中的构造函数的方法应该始终寻找@@ species属性
        class myArray1 {
            //默认@@species。 子类将继承此属性
            static get [Symbol.species]() {
                //默认构造函数
                return this;
            }

            mapping() {
                return new this.constructor[Symbol.species]();
            }
        }
        class myArray2 extends myArray1 {
            static get [Symbol.species]() {
                return myArray1;
            }
        }
        var arr = new myArray2();
        console.log(arr instanceof myArray2); // "true"
        arr = arr.mapping();
        console.log(arr instanceof myArray1); // "true"

        //使用new运算符调用构造函数，则new.target指向此构造函数
        //尚未实施＃448是跟踪 harmony支持的问题 ---未支持
        //        function myConstructor6() {
        //            console.log(new.target.name);
        //        }
        //        class myClass6 extends myConstructor6 {
        //            constructor() {
        //                super();
        //            }
        //        }
        //        var obj1 = new myClass6(); //myClass6
        //        var obj2 = new myConstructor6(); //myConstructor6

        var obj1 = {
            print(){
                console.log("Hello");
            }
        }
        var obj2 = {
            print(){
                super.print();
            }
        }
        Object.setPrototypeOf(obj2, obj1);
        obj2.print(); // "Hello"


    </script>
</head>
<body>

</body>
</html>